package com.anhanguera.tcc.web;

import com.anhanguera.tcc.model.AnexoContrato;
import com.anhanguera.tcc.model.ContratadaPj;
import com.anhanguera.tcc.model.Contrato;
import com.anhanguera.tcc.model.Empenho;
import com.anhanguera.tcc.model.ItemContrato;
import com.anhanguera.tcc.model.NotificacaoAutomatica;
import com.anhanguera.tcc.view.ContratoFacade;
import com.anhanguera.tcc.web.util.JsfUtil;
import com.anhanguera.tcc.web.util.JsfUtil.PersistAction;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Named;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;

@Named("contratoController")
@SessionScoped
public class ContratoController implements Serializable {

    @EJB
    private com.anhanguera.tcc.view.ContratoFacade ejbFacade;

    @EJB
    private com.anhanguera.tcc.view.ContratadaPjFacade ejbContratadaFacade;

    public ContratoController() {
        this.setTabindex(0);
    }

    /* Dados do Contrato */
    private List<Contrato> items = new ArrayList<>();
    private Contrato selected;

    /* Empenhos */
    private List<Empenho> empenhos = new ArrayList<>();
    private Empenho empenhoAdicionar = new Empenho();
    private Empenho empenhoSel = new Empenho();

    /* Partes */
    private ContratadaPj contratadaPj;

    private List<ContratadaPj> listaEmpresas;
    private List<ContratadaPj> listaEmpresasSelecionadas;

    /* Itens */
    private ItemContrato itemContratoAdicionar = new ItemContrato();
    private ItemContrato itemContratoSel = new ItemContrato();
    private List<ItemContrato> itemContratos = new ArrayList<>();

    /* Notificações Automaticas */
    private NotificacaoAutomatica notificacaoAdicionar = new NotificacaoAutomatica();
    private NotificacaoAutomatica notificacaoAutomaticaSel = new NotificacaoAutomatica();
    private List<NotificacaoAutomatica> listaNotificacaoContrato = new ArrayList<>();

    /* Anexos */
    private AnexoContrato anexo = new AnexoContrato();
    private AnexoContrato anexoSelecionado;
    private AnexoContrato anexoAdicionar = new AnexoContrato();
    private List<AnexoContrato> anexos = null;

    private int tabindex;

    public Contrato prepareCreate() {
        listaEmpresas = ejbContratadaFacade.findAll();
        selected = new Contrato();
        this.selected.setInSituacao("1");
        initializeEmbeddableKey();
        return selected;
    }

    public void create() {
        if (this.listaEmpresasSelecionadas != null) {
            this.selected.setContratadaPjList(getListaEmpresasSelecionadas());
        }
        persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("ContratoCreated"));
        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
            empenhos = null;
        }
    }

    public void update() {
        persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("ContratoUpdated"));
    }

    public void destroy() {
        persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("ContratoDeleted"));
        if (!JsfUtil.isValidationFailed()) {
            selected = null; // Remove selection
            items = null;    // Invalidate list of items to trigger re-query.
            empenhos = null;
        }
    }

    public List<Contrato> getItems() {
        if (items == null) {
            items = getFacade().findAll();
        }
        return items;
    }

    private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();

            try {
                if (persistAction != PersistAction.DELETE) {
                    getFacade().edit(selected);
                } else {
                    getFacade().remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                String msg = "";
                Throwable cause = ex.getCause();
                if (cause != null) {
                    msg = cause.getLocalizedMessage();
                }
                if (msg.length() > 0) {
                    JsfUtil.addErrorMessage(msg);
                } else {
                    JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    @FacesConverter(forClass = Contrato.class)
    public static class ContratoControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            ContratoController controller = (ContratoController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "contratoController");
            return controller.getContrato(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Contrato) {
                Contrato o = (Contrato) object;
                return getStringKey(o.getIdContrato());
            } else {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Contrato.class.getName()});
                return null;
            }
        }

    }

    /* Controle do Empenho*/
    public String adicionarEmpenho() {
        System.out.println("reinitEmpenhoAdicionar - nuEmpenho: " + this.getEmpenhoAdicionar().getNuEmpenho());
        if (empenhos == null) {
            empenhos = new ArrayList<>();
        }

        this.empenhos.add(empenhoAdicionar);
        this.empenhoAdicionar = new Empenho();

        return null;
    }

    public void removeEmpenho() {
        this.getEmpenhos().remove(this.getEmpenhoSel());
    }

    /* Controle do Anexo*/
    public String adicionarItens() {
        System.out.println("reinitItensAdicionar - TxDescricao(): " + this.getItemContratoAdicionar().getTxDescricao());
        if (itemContratos == null) {
            itemContratos = new ArrayList<>();
        }
        this.itemContratos.add(itemContratoAdicionar);
        this.itemContratoAdicionar = new ItemContrato();
        return null;
    }

    public String adicionarNotificacao() {
        if (listaNotificacaoContrato == null) {
            listaNotificacaoContrato = new ArrayList<>();
        }
        this.listaNotificacaoContrato.add(notificacaoAdicionar);
        this.notificacaoAdicionar = new NotificacaoAutomatica();
        return null;
    }

    public void removeNotificacao() {
        this.getListaNotificacaoContrato().remove(this.getNotificacaoAutomaticaSel());
    }

    public void removeItens() {
        this.getItemContratos().remove(this.getItemContratoSel());
    }

    public void onRowSelectAnexo(SelectEvent event) {
        this.anexoSelecionado = (AnexoContrato) event.getObject();
    }

    public void onRowUnSelectAnexo(UnselectEvent event) {
        this.anexoSelecionado = null;
    }

    public void removeAnexo() {
        this.getAnexos().remove(this.getAnexoSelecionado());
    }

    public Contrato getSelected() {
        return selected;
    }

    public void setSelected(Contrato selected) {
        this.selected = selected;
    }

    protected void setEmbeddableKeys() {
    }

    protected void initializeEmbeddableKey() {
    }

    private ContratoFacade getFacade() {
        return ejbFacade;
    }

    public int getTabindex() {
        return tabindex;
    }

    public void setTabindex(int tabindex) {
        this.tabindex = tabindex;
    }

    public Empenho getEmpenhoSel() {
        return empenhoSel;
    }

    public void setEmpenhoSel(Empenho empenhoSel) {
        this.empenhoSel = empenhoSel;
    }

    public List<Empenho> getEmpenhos() {
        return empenhos;
    }

    public void setEmpenhos(List<Empenho> empenhos) {
        this.empenhos = empenhos;
    }

    public Empenho getEmpenhoAdicionar() {
        return empenhoAdicionar;
    }

    public void setEmpenhoAdicionar(Empenho empenhoAdicionar) {
        this.empenhoAdicionar = empenhoAdicionar;
    }

    public ContratadaPj getContratadaPj() {
        return contratadaPj;
    }

    public void setContratadaPj(ContratadaPj contratadaPj) {
        this.contratadaPj = contratadaPj;
    }

    public ItemContrato getItemContratoAdicionar() {
        return itemContratoAdicionar;
    }

    public void setItemContratoAdicionar(ItemContrato itemContratoAdicionar) {
        this.itemContratoAdicionar = itemContratoAdicionar;
    }

    public ItemContrato getItemContratoSel() {
        return itemContratoSel;
    }

    public void setItemContratoSel(ItemContrato itemContratoSel) {
        this.itemContratoSel = itemContratoSel;
    }

    public List<AnexoContrato> getAnexos() {
        return anexos;
    }

    public void setAnexos(List<AnexoContrato> anexos) {
        this.anexos = anexos;
    }

    public AnexoContrato getAnexo() {
        return anexo;
    }

    public void setAnexo(AnexoContrato anexo) {
        this.anexo = anexo;
    }

    public AnexoContrato getAnexoAdicionar() {
        return anexoAdicionar;
    }

    public void setAnexoAdicionar(AnexoContrato anexoAdicionar) {
        this.anexoAdicionar = anexoAdicionar;
    }

    public AnexoContrato getAnexoSelecionado() {
        return anexoSelecionado;
    }

    public void setAnexoSelecionado(AnexoContrato anexoSelecionado) {
        this.anexoSelecionado = anexoSelecionado;
    }

    public NotificacaoAutomatica getNotificacaoAdicionar() {
        return notificacaoAdicionar;
    }

    public void setNotificacaoAdicionar(NotificacaoAutomatica notificacaoAdicionar) {
        this.notificacaoAdicionar = notificacaoAdicionar;
    }

    public List<NotificacaoAutomatica> getListaNotificacaoContrato() {
        return listaNotificacaoContrato;
    }

    public void setListaNotificacaoContrato(List<NotificacaoAutomatica> listaNotificacaoContrato) {
        this.listaNotificacaoContrato = listaNotificacaoContrato;
    }

    public NotificacaoAutomatica getNotificacaoAutomaticaSel() {
        return notificacaoAutomaticaSel;
    }

    public void setNotificacaoAutomaticaSel(NotificacaoAutomatica notificacaoAutomaticaSel) {
        this.notificacaoAutomaticaSel = notificacaoAutomaticaSel;
    }

    public List<ContratadaPj> getListaEmpresas() {
        return listaEmpresas;
    }

    public void setListaEmpresas(List<ContratadaPj> listaEmpresas) {
        this.listaEmpresas = listaEmpresas;
    }

    public List<ContratadaPj> getListaEmpresasSelecionadas() {
        return listaEmpresasSelecionadas;
    }

    public void setListaEmpresasSelecionadas(List<ContratadaPj> listaEmpresasSelecionadas) {
        this.listaEmpresasSelecionadas = listaEmpresasSelecionadas;
    }

    public List<ItemContrato> getItemContratos() {
        return itemContratos;
    }

    public void setItemContratos(List<ItemContrato> itemContratos) {
        this.itemContratos = itemContratos;
    }

    public Contrato getContrato(java.lang.Integer id) {
        return getFacade().find(id);
    }

    public List<Contrato> getItemsAvailableSelectMany() {
        return getFacade().findAll();
    }

    public List<Contrato> getItemsAvailableSelectOne() {
        return getFacade().findAll();
    }

}
